package com.junmoo.www.auth.config.authentication;


import com.alibaba.fastjson.JSONObject;;
import com.alibaba.fastjson.parser.Feature;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.HttpMethod;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.server.authentication.ServerFormLoginAuthenticationConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.io.IOException;
import java.util.Map;


/**
 * 获取请求参数，
 * 这里可以对请求参数名称设置；比如 把请求参数 username 改成 name ,把请求参数password 改成 pw
 */
@Component
@Slf4j
public class CloudAuthenticationConverter  extends ServerFormLoginAuthenticationConverter {
    private final String usernameParameter = "username";
    private final String passwordParameter = "password";
    @Override
    public Mono<Authentication> convert(ServerWebExchange exchange) {
        log.info("------ 访问 AuthenticationConverter ------");
        MediaType mediaType = exchange.getRequest().getHeaders().getContentType();
        HttpMethod method = exchange.getRequest().getMethod();
        if(!method.matches(HttpMethod.POST.name())){
            return Mono.error(new Exception("请求 不是 POST method "));
        }
        if(mediaType.equalsTypeAndSubtype(MediaType.APPLICATION_JSON)){
            return  exchange.getRequest().getBody().next().flatMap(body->{
                String username = null;
                String password=null;
                try {
                    Map map = JSONObject.parseObject(body.asInputStream(),Map.class,Feature.AutoCloseSource);
                    username = (String)map.get(this.usernameParameter);
                    password = (String)map.get(this.passwordParameter);
                } catch (IOException e) {
                    e.printStackTrace();
                }
                return Mono.just(new UsernamePasswordAuthenticationToken(username, password));
            });
        }else if(mediaType.equalsTypeAndSubtype(MediaType.APPLICATION_FORM_URLENCODED)){
            return exchange.getFormData().map(data->{
                String username = data.getFirst(this.usernameParameter);
                String password = data.getFirst(this.passwordParameter);
                return new UsernamePasswordAuthenticationToken(username, password);
            });
        }else {
            return Mono.error(new Exception("请求头 Content-Type 不是 application/x-www-form-urlencoded 或 application/json "));
        }
    }
}
